﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SilverlightDatabase;
using System.Collections;
using SilverlightDatabase.Exceptions;

namespace SilverlightDatabaseTest
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void RunTests_Click(object sender, RoutedEventArgs e)
        {

            CreateDBTest();
            CreateTableTest();
            SaveTest();
            OpenTest();
            AddRangeTest();
            RemoveRangeTest();
            RemoveRangeConditionTest();
            SaveFailsTest();
            SaveWithEncryptionTest();
            OpenWithEncryptionTest();
            SelectConditionTest();
            OpenWithCompressionTest();
            OpenWithCompressionEncryptionTest();
            LazyLoadingTest();
        }


        private void CreateDBTest()
        {
            Database.DeleteDatabase("test");
            if (Database.CreateDatabase("TestDatabase") != null)
            {
                this.CreateDatabaseTestLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.CreateDatabaseTestLabel.Foreground = new SolidColorBrush(Colors.Red);
            }
        }

        private void CreateTableTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test");
            db.CreateTable<Person>();

            if (db.Table<Person>() != null)
            {
                db.Table<Person>().Add(NewPerson());
                if (db.Table<Person>().Count == 1)
                {
                    this.CreateTableTestLabel.Foreground = new SolidColorBrush(Colors.Green);
                }
                else
                {
                    this.CreateTableTestLabel.Foreground = new SolidColorBrush(Colors.Red);
                }
            }
            else
            {
                this.CreateTableTestLabel.Foreground = new SolidColorBrush(Colors.Red);
            }

        }

        private void SaveTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test");
            db.CreateTable<Person>();

            if (db.Table<Person>() != null)
            {
                for (int i = 0; i < 20; i++)
                {
                    db.Table<Person>().Add(NewRandomPerson());
                }
                db.Save();
                this.SaveDBLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.SaveDBLabel.Foreground = new SolidColorBrush(Colors.Red);
            }
        }


        private void SaveWithEncryptionTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test", "password");
            db.CreateTable<Person>();

            if (db.Table<Person>() != null)
            {
                for (int i = 0; i < 20; i++)
                {
                    db.Table<Person>().Add(NewRandomPerson());
                }
                db.Save();
                this.SaveDBEncryptionLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.SaveDBEncryptionLabel.Foreground = new SolidColorBrush(Colors.Red);
            }
        }


        private void OpenWithEncryptionTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test", "password");
            db.CreateTable<Person>();

            if (db.Table<Person>() != null)
            {
                for (int i = 0; i < 20; i++)
                {
                    db.Table<Person>().Add(NewRandomPerson());
                }
            }

            db.CreateTable<Phone>();

            if (db.Table<Phone>() != null)
            {
                for (int i = 0; i < 10; i++)
                {
                    db.Table<Phone>().Add(NewRandomPhone());
                }
            }
            db.Save();


            db = Database.OpenDatabase("test", "password");
            if (db.Tables.Count == 2 && db.Table<Person>().Count == 20 && db.Table<Phone>().Count == 10)
            {
                this.OpenDBEncryptionLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.OpenDBEncryptionLabel.Foreground = new SolidColorBrush(Colors.Red);
            }

        }


        private void OpenTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test");
            db.CreateTable<Person>();

            if (db.Table<Person>() != null)
            {
                for (int i = 0; i < 20; i++)
                {
                    db.Table<Person>().Add(NewRandomPerson());
                }
            }

            db.CreateTable<Phone>();

            if (db.Table<Phone>() != null)
            {
                for (int i = 0; i < 10; i++)
                {
                    db.Table<Phone>().Add(NewRandomPhone());
                }
            }
            db.Save();


            db = Database.OpenDatabase("test");
            if (db.Tables.Count == 2 && db.Table<Person>().Count == 20 && db.Table<Phone>().Count == 10)
            {
                this.OpenDBLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.OpenDBLabel.Foreground = new SolidColorBrush(Colors.Red);
            }

        }

        private void AddRangeTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test");
            db.CreateTable<Person>();
            List<Person> list = new List<Person>();
            if (db.Table<Person>() != null)
            {
                for (int i = 0; i < 20; i++)
                {
                    list.Add(NewRandomPerson());
                }
            }

            db.Table<Person>().AddRange(list);
            db.Save();

            db = Database.OpenDatabase("test");
            if (db.Tables.Count == 1 && db.Table<Person>().Count == 20)
            {
                this.AddRangeLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.AddRangeLabel.Foreground = new SolidColorBrush(Colors.Red);
            }

        }

        private void RemoveRangeTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test");
            db.CreateTable<Person>();

            Person person1 = new Person() { FirstName = "John ", LastName = "Doe ", Salary = 1, BirthDate = new DateTime(1900, 1, 1) };
            Person person2 = new Person() { FirstName = "John ", LastName = "Doe ", Salary = 2, BirthDate = new DateTime(1900, 1, 1) };
            Person person3 = new Person() { FirstName = "John ", LastName = "Doe ", Salary = 3, BirthDate = new DateTime(1900, 1, 1) };

            db.Table<Person>().Add(person1);
            db.Table<Person>().Add(person2);
            db.Table<Person>().Add(person3);

            db.Table<Person>().Remove(person2);

            db.Save();

            db = Database.OpenDatabase("test");
            if (db.Tables.Count == 1 && db.Table<Person>().Count == 2)
            {
                this.RemoveRangeLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.RemoveRangeLabel.Foreground = new SolidColorBrush(Colors.Red);
            }

        }

        private void RemoveRangeConditionTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test");
            db.CreateTable<Person>();

            Person person1 = new Person() { FirstName = "John ", LastName = "Doe ", Salary = 1, BirthDate = new DateTime(1900, 1, 1) };
            Person person2 = new Person() { FirstName = "John ", LastName = "Doe ", Salary = 2, BirthDate = new DateTime(1900, 1, 1) };
            Person person3 = new Person() { FirstName = "John ", LastName = "Doe ", Salary = 3, BirthDate = new DateTime(1900, 1, 1) };

            db.Table<Person>().Add(person1);
            db.Table<Person>().Add(person2);
            db.Table<Person>().Add(person3);

            db.Table<Person>().RemoveRange(
                (person) => { return (person.Salary >= 2); });

            db.Save();

            db = Database.OpenDatabase("test");
            if (db.Tables.Count == 1 && db.Table<Person>().Count == 1)
            {
                this.RemoveRangeViaConditionLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.RemoveRangeViaConditionLabel.Foreground = new SolidColorBrush(Colors.Red);
            }

        }

        private void SelectConditionTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test");
            db.CreateTable<Person>();

            Person person1 = new Person() { FirstName = "John ", LastName = "Doe ", Salary = 1, BirthDate = new DateTime(1900, 1, 1) };
            Person person2 = new Person() { FirstName = "John ", LastName = "Doe ", Salary = 2, BirthDate = new DateTime(1900, 1, 1) };
            Person person3 = new Person() { FirstName = "John ", LastName = "Doe ", Salary = 3, BirthDate = new DateTime(1900, 1, 1) };

            db.Table<Person>().Add(person1);
            db.Table<Person>().Add(person2);
            db.Table<Person>().Add(person3);

            var query = (from onePerson in db.Table<Person>()
                         where onePerson.Salary == 2
                         select onePerson);



            if (query.Count() == 1)
            {
                this.LinqSelectTestLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.LinqSelectTestLabel.Foreground = new SolidColorBrush(Colors.Red);
            }

        }

        private void OpenWithCompressionTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test", true);
            db.CreateTable<Person>();

            if (db.Table<Person>() != null)
            {
                for (int i = 0; i < 20; i++)
                {
                    db.Table<Person>().Add(NewRandomPerson());
                }
            }

            db.CreateTable<Phone>();

            if (db.Table<Phone>() != null)
            {
                for (int i = 0; i < 10; i++)
                {
                    db.Table<Phone>().Add(NewRandomPhone());
                }
            }
            db.Save();


            db = Database.OpenDatabase("test", true);
            if (db.Tables.Count == 2 && db.Table<Person>().Count == 20 && db.Table<Phone>().Count == 10)
            {
                this.CompressionTestLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.CompressionTestLabel.Foreground = new SolidColorBrush(Colors.Red);
            }

        }

        private void LazyLoadingTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test", "password", true);
            db.CreateTable<Person>();

            if (db.Table<Person>() != null)
            {
                for (int i = 0; i < 20; i++)
                {
                    db.Table<Person>().Add(NewRandomPerson());
                }
            }

            db.CreateTable<Phone>();

            if (db.Table<Phone>() != null)
            {
                for (int i = 0; i < 10; i++)
                {
                    db.Table<Phone>().Add(NewRandomPhone());
                }
            }
            db.Save();


            db = Database.OpenDatabase("test", "password", true, true);
            if (db.Tables.Count == 2)
            {
                if (((ICollection)db.Tables[0]).Count == 0 && ((ICollection)db.Tables[1]).Count == 0)
                {
                    if (db.Table<Person>().Count == 20 && db.Table<Phone>().Count == 10)
                    {
                        this.LazyLoadingTestLabel.Foreground = new SolidColorBrush(Colors.Green);
                    }
                    else
                    {
                        this.LazyLoadingTestLabel.Foreground = new SolidColorBrush(Colors.Red);
                    }
                }
                else
                {
                    this.LazyLoadingTestLabel.Foreground = new SolidColorBrush(Colors.Red);
                }
            }


        }

        private void OpenWithCompressionEncryptionTest()
        {
            Database.DeleteDatabase("test");
            Database db = Database.CreateDatabase("test", "password", true);
            db.CreateTable<Person>();

            if (db.Table<Person>() != null)
            {
                for (int i = 0; i < 20; i++)
                {
                    db.Table<Person>().Add(NewRandomPerson());
                }
            }

            db.CreateTable<Phone>();

            if (db.Table<Phone>() != null)
            {
                for (int i = 0; i < 10; i++)
                {
                    db.Table<Phone>().Add(NewRandomPhone());
                }
            }
            db.Save();


            db = Database.OpenDatabase("test", "password", true);
            if (db.Tables.Count == 2 && db.Table<Person>().Count == 20 && db.Table<Phone>().Count == 10)
            {
                this.CompressionEncryptionTestLabel.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.CompressionEncryptionTestLabel.Foreground = new SolidColorBrush(Colors.Red);
            }

        }

        private void SaveFailsTest()
        {
            Table<Person> table = new Table<Person>();

            Person person1 = new Person() { FirstName = "John ", LastName = "Doe ", Salary = 1, BirthDate = new DateTime(1900, 1, 1) };
            table.Add(person1);

            try
            {
                table.Save();
                this.SaveTableFailsLabel.Foreground = new SolidColorBrush(Colors.Red);
            }
            catch (TableCannotBeSavedException)
            {
                this.SaveTableFailsLabel.Foreground = new SolidColorBrush(Colors.Green);
            }



        }

        private Person NewPerson()
        {
            return new Person() { FirstName = "John", LastName = "Doe", Salary = 100, BirthDate = new DateTime(1900, 1, 1) };
        }

        private Person NewRandomPerson()
        {
            Random rand = new Random();
            return new Person() { FirstName = "John " + rand.Next(), LastName = "Doe " + rand.Next(), Salary = rand.Next(), BirthDate = new DateTime(1900 + rand.Next(1, 99), 1, 1) };
        }

        private Phone NewRandomPhone()
        {
            Random rand = new Random();
            return new Phone() { PhoneNumber = rand.Next().ToString(), Extension = rand.Next().ToString() };
        }
    }
}
